# Copyright 2024 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

load("@rules_cc//cc/toolchains:tool.bzl", "cc_tool")
load("@rules_cc//cc/toolchains:tool_map.bzl", "cc_tool_map")

licenses(["notice"])

# This `select` happens under the target configuration. For macOS,
# llvm-libtool-darwin should be used when creating static libraries even if the
# exec platform is linux.
alias(
    name = "all_tools",
    actual = select({
        "@platforms//os:macos": ":macos_tools",
        "//conditions:default": ":default_tools",
    }),
    visibility = ["//visibility:public"],
)

COMMON_TOOLS = {
    "@rules_cc//cc/toolchains/actions:assembly_actions": ":clang",
    "@rules_cc//cc/toolchains/actions:c_compile": ":clang",
    "@rules_cc//cc/toolchains/actions:cpp_compile_actions": ":clang++",
    "@rules_cc//cc/toolchains/actions:link_actions": ":lld",
    "@rules_cc//cc/toolchains/actions:objcopy_embed_data": ":llvm-objcopy",
    "@rules_cc//cc/toolchains/actions:strip": ":llvm-strip",
}

cc_tool_map(
    name = "default_tools",
    tools = COMMON_TOOLS | {
        "@rules_cc//cc/toolchains/actions:ar_actions": ":llvm-ar",
    },
    visibility = ["//visibility:private"],
)

cc_tool_map(
    name = "macos_tools",
    tools = COMMON_TOOLS | {
        "@rules_cc//cc/toolchains/actions:ar_actions": ":llvm-libtool-darwin",
    },
    visibility = ["//visibility:private"],
)

cc_tool(
    name = "clang",
    src = select({
        "//constraint:linux_aarch64": "@clang-linux-aarch64//:bin/clang",
        "//constraint:linux_x86_64": "@clang-linux-x86_64//:bin/clang",
    }),
    data = [
        ":exec_platform_builtin_headers",
        ":exec_platform_multicall_support_files",
    ],
)

cc_tool(
    name = "clang++",
    src = select({
        "//constraint:linux_aarch64": "@clang-linux-aarch64//:bin/clang++",
        "//constraint:linux_x86_64": "@clang-linux-x86_64//:bin/clang++",
    }),
    data = [
        ":exec_platform_builtin_headers",
        ":exec_platform_multicall_support_files",
    ],
)

cc_tool(
    name = "lld",
    src = select({
        "//constraint:linux_aarch64": "@clang-linux-aarch64//:bin/clang++",
        "//constraint:linux_x86_64": "@clang-linux-x86_64//:bin/clang++",
    }),
    data = [
        ":exec_platform_builtin_headers",
        ":exec_platform_linker_builtins",
        ":exec_platform_multicall_support_files",
    ],
)

cc_tool(
    name = "llvm-ar",
    src = select({
        "//constraint:linux_aarch64": "@clang-linux-aarch64//:bin/llvm-ar",
        "//constraint:linux_x86_64": "@clang-linux-x86_64//:bin/llvm-ar",
    }),
    data = [":exec_platform_multicall_support_files"],
)

cc_tool(
    name = "llvm-libtool-darwin",
    src = select({
        "//constraint:linux_aarch64": "@clang-linux-aarch64//:bin/llvm-libtool-darwin",
        "//constraint:linux_x86_64": "@clang-linux-x86_64//:bin/llvm-libtool-darwin",
    }),
    data = [":exec_platform_multicall_support_files"],
)

cc_tool(
    name = "llvm-objcopy",
    src = select({
        "//constraint:linux_aarch64": "@clang-linux-aarch64//:bin/llvm-objcopy",
        "//constraint:linux_x86_64": "@clang-linux-x86_64//:bin/llvm-objcopy",
    }),
    data = [":exec_platform_multicall_support_files"],
)

cc_tool(
    name = "llvm-objdump",
    src = select({
        "//constraint:linux_aarch64": "@clang-linux-aarch64//:bin/llvm-objdump",
        "//constraint:linux_x86_64": "@clang-linux-x86_64//:bin/llvm-objdump",
    }),
    data = [":exec_platform_multicall_support_files"],
)

cc_tool(
    name = "llvm-cov",
    src = select({
        "//constraint:linux_aarch64": "@clang-linux-aarch64//:bin/llvm-cov",
        "//constraint:linux_x86_64": "@clang-linux-x86_64//:bin/llvm-cov",
    }),
    data = [":exec_platform_multicall_support_files"],
)

cc_tool(
    name = "llvm-strip",
    src = select({
        "//constraint:linux_aarch64": "@clang-linux-aarch64//:bin/llvm-strip",
        "//constraint:linux_x86_64": "@clang-linux-x86_64//:bin/llvm-strip",
    }),
    data = [":exec_platform_multicall_support_files"],
)

cc_tool(
    name = "clang-tidy",
    src = select({
        "//constraint:linux_aarch64": "@clang-linux-aarch64//:bin/clang-tidy",
        "//constraint:linux_x86_64": "@clang-linux-x86_64//:bin/clang-tidy",
    }),
    data = [
        ":exec_platform_builtin_headers",
        ":exec_platform_multicall_support_files",
    ],
)

#################################
#   Platform-specific aliases   #
#################################

# These aliases are used to reduce duplication of `select` statements throughout
# this build file. The select statements in these aliases are evaluated under
# the exec configuration.

alias(
    name = "exec_platform_builtin_headers",
    actual = select({
        "//constraint:linux_aarch64": "@clang-linux-aarch64//:builtin_headers",
        "//constraint:linux_x86_64": "@clang-linux-x86_64//:builtin_headers",
    }),
    visibility = ["//visibility:private"],
)

alias(
    name = "exec_platform_multicall_support_files",
    actual = select({
        "//constraint:linux_aarch64": "@clang-linux-aarch64//:multicall_support_files",
        "//constraint:linux_x86_64": "@clang-linux-x86_64//:multicall_support_files",
    }),
    visibility = ["//visibility:private"],
)

alias(
    name = "exec_platform_linker_builtins",
    actual = select({
        "//constraint:linux_aarch64": "@clang-linux-aarch64//:linker_builtins",
        "//constraint:linux_x86_64": "@clang-linux-x86_64//:linker_builtins",
    }),
    visibility = ["//visibility:private"],
)
